﻿using CommandSystem;
using CustomCharacter;
using Exiled.API.Enums;
using Exiled.API.Features;
using Exiled.API.Features.Pools;
using Exiled.API.Features.Roles;
using HarmonyLib;
using MEC;
using PlayerRoles;
using RemoteAdmin;
using Respawning;
using RgCore.GameData;
using RgCore.API;
using RgCore.PlayerHud;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using RgCore.CustomSide;
using UnityEngine;
using RgCore.Modules;

namespace Customize
{
    public static class Extensions
    {
        private static bool CustomScpInternal(Player player) => player.GetSide() == Side.Scp && player.IsCustomCharacter();

        public static bool IsCustomScp(this Player player)
        {
            if (ModuleManager.IsLoaded("CustomCharacter"))
            {
                return CustomScpInternal(player);
            }
            return false;
        }
        public static string GetCustomRoleName(this Player player) => MethodExtensions.GetCustomRoleName(player);

        public static bool IsScp(this Player player) => player.IsScp || IsCustomScp(player);

        
    }

    public static class BasicHandler
    {

        public static string[] ScpHud(Player player)
        {
            if (!player.IsScp())
            {
                player.DeleteMsg("scphud", false);
                return new string[] { "" };
            }
            List<string> str_list = new List<string>();
            var list = Player.List.Where(x => ((x.IsScp && x.Role.Type != RoleTypeId.Scp0492) || x.IsCustomScp()) && x != player).ToList();
            string text = $"<color=red>团队 {list.Count}👥</color>";
            if (list.Count == 0)
                text += " | <color=#ff9300>你是SCP阵营最后一员 祝你好运</color>";
            int count = 0;
            foreach (Player scp in list)
            {
                if (count >= 5)
                {
                    count = 0;
                    str_list.Add(text);
                    text = String.Empty;
                }
                string hex = "#6b0000";
                float percent = scp.Health / scp.MaxHealth;
                if (percent > 0.3)
                    hex = "#ff7a00";
                if (percent > 0.6)
                    hex = "#ffff00";
                if (percent > 0.8)
                    hex = "#00ff00";
                if (scp.IsCustomScp())
                    text += $" | {scp.GetCustomRoleName()}: ";
                else
                    text += $" | <color=#FF0000>{scp.Role.Name}</color>: ";
                if (scp.Role is Scp079Role s0)
                    text += $"<color=#00FFFF>[{s0.Level}]</color> <color=#FF08E8>{(int)s0.AuxManager.CurrentAux}</color>";
                else if (scp.HumeShield > 0)
                    text += $"<color=#6f57c4>{(int)scp.HumeShield}</color>";
                else if (scp.ArtificialHealth > 0)
                    text += $"<color=#08c985>{(int)scp.ArtificialHealth}</color>";
                else
                    text += $"<color={hex}>{(int)scp.Health}</color>";
                count++;
            }
            if (!string.IsNullOrEmpty(text))
                str_list.Add(text);
            for (int i = 0; i < str_list.Count; i++)
                str_list[i] = $"<size=80%>{str_list[i]}</size>";
            return str_list.ToArray();
        }

        public static string[] RespawnHud(Player player)
        {
            int second = RespawnManager.Singleton.TimeTillRespawn;
            string text = $"新的一波增援将在<color=yellow> {second} </color>秒后刷新";
            string team = RespawnManager.Singleton.NextKnownTeam == Respawning.SpawnableTeamType.NineTailedFox ? "<color=#1E90FF>MTF</color>" : "<color=green>CI</color>";
            switch (RespawnManager.CurrentSequence())
            {
                case RespawnManager.RespawnSequencePhase.PlayingEntryAnimations:
                    text += $" | 锁定: {team}"; break;
            }
            return new string[] { text };
        }

        public static CoroutineHandle Coroutine;

        public static void Update()
        {
            while (true)
            {
                try
                {
                    if (Round.IsStarted)
                    {
                        foreach (Player player in Player.List)
                        {
                            if (player == null)
                                continue;
                            if (player.Velocity.y < -100)
                            {
                                Vector3 current = player.Position;
                                Dictionary<Room, float> rooms = DictionaryPool<Room, float>.Pool.Get();
                                foreach (var room in Room.List.Where(x => (!Map.IsLczDecontaminated || x.Zone != ZoneType.LightContainment) && (!Warhead.IsDetonated || x.Zone == ZoneType.Surface)))
                                {
                                    rooms.Add(room, Vector3.Distance(current, room.Transform.position));
                                }
                                Room target_room = rooms.Where(x => x.Key.Doors.Any()).FirstOrDefault(x => x.Value == rooms.Values.Min()).Key;
                                if (target_room == null)
                                {
                                    player.Kill("掉出了这个世界");
                                }
                                else
                                {
                                    player.IsGodModeEnabled = true;
                                    player.Teleport(target_room.Doors.ElementAt(0).Position + (Vector3.up * 1.5f));
                                    Timing.CallDelayed(1.0f, () => player.IsGodModeEnabled = false);
                                    player.SendFormattedMsg("void_check", "<color=#FFD700>虚空检测</color>", "检测到您意外卡入了虚空？已为您传送到最近可用房间内", 3, MsgType.Announcement, ScreenLocation.CenterTop, true);
                                }
                            }
                            //if (player.IsScp() && !player.HasMsg("scphud"))
                            //{
                            //    player.SendRawMsg("scphud", ScpHud, 0, ScreenLocation.Top, false);
                            //}
                            if (ServerStatic.StopNextRound == ServerStatic.NextRoundAction.Shutdown)
                            {
                                if (!player.HasMsg("nextround"))
                                {
                                    player.SendRawMsg("nextround", $"<b><color=#EE6363>⚠回合结束后将关闭服务器⚠</color></b>", 0, ScreenLocation.Top, false);
                                }
                            }
                            else
                            {
                                if (player.HasMsg("nextround"))
                                {
                                    player.DeleteMsg("nextround", false);
                                }
                            }
                            if (Round.IsLocked)
                            {
                                if (!player.HasMsg("round_locked"))
                                {
                                    player.SendRawMsg("round_locked", "🔒 回合已锁定 🔒", 0, ScreenLocation.Top, false);
                                }
                            }
                            else
                            {
                                if (player.HasMsg("round_locked"))
                                {
                                    player.DeleteMsg("round_locked", false);
                                }
                            }
                            if (player.IsGodModeEnabled)
                            {
                                if (!player.HasMsg("god_enabled"))
                                {
                                    player.SendRawMsg("god_enabled", "<color=#A90308><b>[GOD] 上帝模式 [GOD]</b></color>", 0, ScreenLocation.Top, false);
                                }
                            }
                            else
                            {
                                if (player.HasMsg("god_enabled"))
                                {
                                    player.DeleteMsg("god_enabled", false);
                                }
                            }
                            if (RespawnManager.Singleton.TimeTillRespawn < 30 && Round.IsStarted && !player.IsAlive)
                            {
                                if (!player.HasMsg("respawn"))
                                {
                                    player.SendRawMsg("respawn", RespawnHud, 30, ScreenLocation.Top, false);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                }
                Thread.Sleep(200);
            }
        }
    }

    public class SizeCommand : ICommand
    {
        public string Command => "size";

        public string[] Aliases => Array.Empty<string>();

        public string Description => "修改玩家模型大小";

        public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
        {
            if (arguments.Count < 4)
            {
                response = "用法：size <ID> <x> <y> <z>";
                return false;
            }
            if (!int.TryParse(arguments.At(0), out int id))
            {
                response = "未提供有效的ID";
                return false;
            }
            if (!float.TryParse(arguments.At(1), out float x) || !float.TryParse(arguments.At(2), out float y) || !float.TryParse(arguments.At(3), out float z))
            {
                response = "未提供有效的比例";
                return false;
            }
            Player player = Player.Get(id);
            if (player == null)
            {
                response = "玩家不存在";
                return false;
            }
            player.Scale = new UnityEngine.Vector3(x, y, z);
            response = "成功";
            return true;
        }
    }

    public class TestCommand : ICommand
    {
        public string Command => "test";

        public string[] Aliases => Array.Empty<string>();

        public string Description => "测试命令";

        public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
        {
            response = "NOPE";
            if (arguments.ElementAt(0) == "x")
            {
                response = $"探测路径：{AppDomain.CurrentDomain.BaseDirectory}";

                return true;
            }
            return false;
        }
    }

    public class PluginEntry : RgPlugin
    {
        public override string Name => "风格化模块";

        public override PluginPriority Priority => PluginPriority.Lowest;

        public override string Id => "customize";
        public Harmony HarmonyPatch { get; private set; }
        public Thread Thread;

        public override void OnEnabled()
        {
            Exiled.Events.Handlers.Player.ChangingSpectatedPlayer += Player_ChangingSpectatedPlayer;
            Exiled.Events.Handlers.Player.ChangingRole += Player_ChangingRole;
            CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(new TestCommand());
            CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(new SizeCommand());
            HarmonyPatch = new Harmony(Id);
            Thread = new Thread(BasicHandler.Update) { Name = "风格化模块" };
            Thread.Start();
        }
        private void Player_ChangingRole(Exiled.Events.EventArgs.Player.ChangingRoleEventArgs ev)
        {
            if ((ev.NewRole.GetTeam() == Team.ChaosInsurgency || ev.NewRole.GetTeam() == Team.FoundationForces) && ev.SpawnFlags == RoleSpawnFlags.All)
            {
                ev.Player.IsGodModeEnabled = true;
                ev.Player.SendRawMsg("spawn_protect", "<color=#6782fb>🔰 出生保护激活中 🔰</color>", 15U, ScreenLocation.Top, false);
                Timing.CallDelayed(15f, delegate ()
                {
                    ev.Player.IsGodModeEnabled = false;
                });
            }
        }

        //private string GetCustomRoleName(Player player, string str)
        //{
        //    if (player != null)
        //    {
        //        var cc = player.GetCharacterInstance();
        //        if (cc != null && cc.VisibleForTeam != SideType.Scp)
        //        {
        //            str = $"<color={cc.RoleColor.ColorToHex()}>{cc.Attribute.Name}</color>";
        //        }
        //    }
        //    return str;
        //}

        private void Player_ChangingSpectatedPlayer(Exiled.Events.EventArgs.Player.ChangingSpectatedPlayerEventArgs ev)
        {
            if (ModuleManager.IsLoaded("CustomCharacter"))
            {
                Exiled.Events.Handlers.Player.ChangingSpectatedPlayer -= Player_ChangingSpectatedPlayer;
                return;
            }
            if (ev.NewTarget != null)
            {
                if (ev.Player.HasMsg("spectator"))
                {
                    ev.Player.DeleteMsg("spectator", false);
                }
                string rolename = $"<color={ev.NewTarget.Role.Color.ToHex()}>{ev.NewTarget.Role.Type.GetRoleName()}</color>";
                var data = GameplayData.GameDatas.FirstOrDefault(x => x.Player == ev.NewTarget);
                if (data != null)
                {
                    ev.Player.SendRawMsg("spectator",
                        $"正在观看：{rolename} | 等级: {GameplayData.GetLevelText(data.Transmigration, data.Level, true)}", 10, ScreenLocation.Bottom, true);
                }
            }
        }

        public override void OnDisabled()
        {
            HarmonyPatch.UnpatchAll(Id);
            Exiled.Events.Handlers.Player.ChangingSpectatedPlayer -= Player_ChangingSpectatedPlayer;
            Exiled.Events.Handlers.Player.ChangingRole -= Player_ChangingRole;
            CommandProcessor.RemoteAdminCommandHandler.UnregisterCommand(CommandProcessor.RemoteAdminCommandHandler.AllCommands.FirstOrDefault(x => x is TestCommand));
            CommandProcessor.RemoteAdminCommandHandler.UnregisterCommand(CommandProcessor.RemoteAdminCommandHandler.AllCommands.FirstOrDefault(x => x is SizeCommand));
            Thread.Abort();
        }
    }
}